#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk.h>

#include <mach/hardware.h>
#include <mach/system.h>
#include <mach/device.h>
#include <mach/regs-pwm.h>

#include "leds_class_ry.h"
//  int (*probe)(struct platform_device *);
//  int (*remove)(struct platform_device *);
//  void (*shutdown)(struct platform_device *);
//  int (*suspend)(struct platform_device *, pm_message_t state);
//  int (*resume)(struct platform_device *);
//  struct device_driver driver;
//  const struct platform_device_id *id_table;

struct mxs_leds  {
  struct led_classdev classdev;
  const char* name;
  unsigned  int num;
  struct mxs_led* leds;
};

static struct mxs_leds m_leds;

static void leds_ry_brightness_set(struct mxs_led *pled, enum led_brightness value) {
  pled->led_set(pled->index, value);
}

static int __devinit leds_ry_probe(struct platform_device* pdev) {
  struct mxs_leds_plat_data* plat_data = NULL;
  struct led_classdev* pclass_dev = NULL;
  int i;

  plat_data = (struct mxs_leds_plat_data*)pdev->dev.platform_data;
  if (NULL == plat_data) {
    return -ENODEV;
  }
  // fill the local values
  m_leds.num = 1;
  //plat_data->num;
  m_leds.leds = plat_data->leds;
  // print the device struct
  printk(KERN_DEBUG "leds data: num=%d\n", m_leds.num);
  // fill the struct
  for (i = 0; i < m_leds.num; i++) {
    int rc = 0;
    // get the class struct ,because of the infomation beyond to device
    // class dev can be define in leds data
    pclass_dev = &(m_leds.leds[i].dev);
    // fill the class variable
    pclass_dev->name = m_leds.leds[i].name;
    //pclass_dev->flags = 0;
    //pclass_dev->brightness_set = 

    rc = leds_class_ry_register(&pdev->dev, pclass_dev);
    
    if (rc < 0) {
      dev_err(&pdev->dev, "Unable to register LED device %d (err=%d)\n", i, rc);
      
    }
    leds_ry_brightness_set(&m_leds.leds[i], LED_FULL);
  }
  // the driver have no infomations
  // fill the information




  printk(KERN_DEBUG "leds ry probe");
  return 0;
}

static int __devexit leds_ry_remove(struct platform_device* pdev) {
  return 0;
}

static struct platform_driver ry_led_driver = {
  .probe = leds_ry_probe,
  .remove = leds_ry_remove,
  .driver = {
    .name = "mxs-leds",  //!< with no name will crash
  }
};

static int __exit leds_ry_init(void) {
  int ret = 0;
  printk(KERN_DEBUG "-------\nplatform driver register\n");
  ret = platform_driver_register(&ry_led_driver);
  return ret;
}

static void __exit leds_ry_exit(void) {
  int i = 0;
  for (i = 0;i < m_leds.num;i++) {
    leds_class_ry_unregister(&(m_leds.leds[i].dev));
  }
  platform_driver_unregister(&ry_led_driver);
  printk(KERN_DEBUG "platform driver unregister\n");
}

module_init(leds_ry_init);
module_exit(leds_ry_exit);

MODULE_AUTHOR("REN suiyi");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0.0");
MODULE_DESCRIPTION("led driver");
